from datetime import date
from io import DEFAULT_BUFFER_SIZE
import json
import math
import random
import csv
import ctypes
from tkinter.constants import PROJECTING
import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# import sesson3.subject1.ss3_1 as s31
# import sesson3.subject1.base_fun as bf
import sesson3.subject1.networkx_graph31 as ng31
# from .import base_fun as bf
# from .import sesson2_2_main as s22
# from .import networkx_graph31 as ng31
import networkx as nx
colors = list(dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS).keys())
def id2points(path_id, points):
    path_points = []
    px = {"longitude": 105.53628319629698, "latitude": 38.832731900565818}
    path_point_json = []
    pdict = dict()
    for (key, paths) in path_id.items():
        _points_2=[]
        jsond3_2=[]
        for line in paths:  # 每条路
            # print(line)
            _points = list()
            jsond3 = list()
            for val in line:
                _points.append(points[val])
                px["latitude"] = points[val][1]
                px["longitude"] = points[val][0]
                jsond3.append(px.copy())
        _points_2.append(_points.copy())
        jsond3_2.append(jsond3.copy())
        
        path_id[key] = (paths.copy(), _points_2.copy(), jsond3_2)
    # return path_points, path_point_json
def id2points_old(path_id, points, place_id):
    path_points = []
    px = {"longitude": 105.53628319629698, "latitude": 38.832731900565818}
    path_point_json = []
    for line_id in path_id:  # 每条路
        # print(line)
        _points = list()
        jsond3 = list()
        for val in line_id:#每个点
            _points.append(points[val])
            px["latitude"] = points[val][1]
            px["longitude"] = points[val][0]
            jsond3.append(px.copy())
        path_points.append(_points.copy())
        path_point_json.append(jsond3.copy())
    return path_points,path_point_json
def GetDistance(p1, p2):
    lat1 = p1[1]
    long1 = p1[0]
    lat2 = p2[1]
    long2 = p2[0]
    if (lat1 == lat2) and long1 == long2:
        return -1
    val = np.sin(lat1 * 0.01745329) * np.sin(lat2 * 0.01745329) + np.cos(lat1 *
                                                                         0.01745329) * np.cos(lat2 * 0.01745329) * np.cos((long1 - long2) * 0.01745329)
    if(val > 1):
        # print(p1,p2)
        return -1
    return 6378137 * np.arccos(val)
class People():
    def __init__(self, speed, pass_point, pass_id) -> None:
        self.speed = speed
        self.has_pass = 0
        self.pass_now_id = 0
        self.pass_id = pass_id
        self.pass_point = pass_point
        self.cip = []
        self.new_start = 0
        self.new_pass_id = []
        self.new_pass_point = []
        self.new_pass_point_json = []
        self.old_pass_point = []
        self.old_pass_id = []
        self.old_pass_point_json = []
        # print(pass_point)
        self.get_cip()

    def get_cip(self):
        for i in range(len(self.pass_point)-1):
            val = GetDistance(self.pass_point[i], self.pass_point[i+1])
            self.cip.append(val)
        # print(self.cip)

    def get_pass_id(self):
        sum = 0
        for id, val in enumerate(self.cip):
            sum += val
            if(sum > self.has_pass):
                return id
        return id

    def outpath(self):

        return self.pass_point[:self.get_pass_id()]
def read_client_path(path_name):
    # path_name = "D:/session/session_3/subject_1/subject_1_train_data/client_path_" + \

    print("client:",path_name)
    with open(path_name, 'r') as load_f:
        load_dict = json.load(load_f)

    rescue_peoples = []
    people_id = []
    people_type = []
    start_points = []
    break_points = []
    for rescue_people in load_dict["people"]:
        # print(rescue_people)
        rescue_peoples.append(
            [rescue_people["people_point"]["longitude"], rescue_people["people_point"]["latitude"]])
        people_type.append(rescue_people["people_type"])
        people_id.append(rescue_people["people_id"])

    for breaks_places in load_dict["breaks"]:
        # print(rescue_people)
        # print("start",breaks_places["break_start_point"])
        # print("end",breaks_places["break_end_point"])
        break_points.append([breaks_places["break_start_point"]["longitude"],
                             breaks_places["break_start_point"]["latitude"]])
        break_points.append([breaks_places["break_end_point"]["longitude"],
                             breaks_places["break_end_point"]["latitude"]])

        # rescue_peoples.append([rescue_people["people_point"]
        #                        ["longitude"], rescue_people["people_point"]["latitude"]])
        # people_type.append(rescue_people["people_type"])
        # people_id.append(rescue_people["people_id"])
    # print(break_points)
    for po in load_dict["init_points"]:
        start_points.append([po["longitude"], po["latitude"]])
    place_points = []
    place_id=[]
    place_type=[]
    
    for po in load_dict["place_points"]:
        place_id.append(po["place_id"])
        place_type.append(po["place_type"])
        place_points.append(
            [po["place_point"]["longitude"], po["place_point"]["latitude"]])
    return rescue_peoples, people_id, people_type, start_points, place_points, break_points,(place_id,place_type)


# 收到动态信息后再读取原文件的newbreaks
def read_new_break(session, round, jsonPath):
    client_path = json.load(open(jsonPath, "r", encoding="utf-8"))
    break_2_point=[]
    # 统一new break的经纬度小数位
    for i in range(len(client_path["newBreaks"])):
        client_path["newBreaks"][i]["break_start_point"]["longitude"] = float(format(client_path["newBreaks"][i]["break_start_point"]["longitude"], ".8f"))
        client_path["newBreaks"][i]["break_start_point"]["latitude"] = float(format(client_path["newBreaks"][i]["break_start_point"]["latitude"], ".8f"))
        client_path["newBreaks"][i]["break_end_point"]["longitude"] = float(format(client_path["newBreaks"][i]["break_end_point"]["longitude"], ".8f"))
        client_path["newBreaks"][i]["break_end_point"]["latitude"] = float(format(client_path["newBreaks"][i]["break_end_point"]["latitude"], ".8f"))


        break_2_point.append([client_path["newBreaks"][i]["break_start_point"]["longitude"],
                             client_path["newBreaks"][i]["break_start_point"]["latitude"]])
        break_2_point.append([client_path["newBreaks"][i]["break_end_point"]["longitude"],
                             client_path["newBreaks"][i]["break_end_point"]["latitude"]])


    print("Read dynamic information successfully: Session:%d, Subject:%d, Round:%d" % (session, 2, round))
    return client_path,break_2_point


def GetDistance(p1, p2):
    lat1 = p1[1]
    long1 = p1[0]
    lat2 = p2[1]
    long2 = p2[0]
    if (lat1 == lat2) and long1 == long2:
        return -1
    val = np.sin(lat1 * 0.01745329) * np.sin(lat2 * 0.01745329) + np.cos(lat1 *
                                                                         0.01745329) * np.cos(lat2 * 0.01745329) * np.cos((long1 - long2) * 0.01745329)
    if(val > 1):
        # print(p1,p2)
        return -1
    return 6378137 * np.arccos(val)

def read_client_data(round_id):
    #人的坐标 人的ID，起点 ，安全区，断点
    d1, pds, pty, start_points, place_points, break_points,place_map_points = read_client_path(
        round_id)

    data1 = pd.DataFrame(np.array(d1), columns=['longitude', 'latitude'])
    data2 = pd.DataFrame(np.array(pds), columns=['people_id'])
    data3 = pd.DataFrame(np.array(pty), columns=['people_type'])

    data_set = pd.concat([data1, data2, data3], axis=1)
    # print(data_set)
    return data_set, start_points, place_points,break_points,place_map_points

# out_data(1)


def GET_my_path(npallp, ps):

    _ldd = 0
    pltlins = []
    D5 = []
    for line in ps:  # 循环输出csv中的所有数据
        d3 = []
        for val in line:
            d3.append(npallp[val])
        # print(d3)
        d4 = np.array(d3)
        plt.plot(d4[:, 1], d4[:, 0], color=colors[_ldd+2],
                 marker='.', label=str(_ldd))
        plt.scatter(d4[:, 1][0], d4[:, 0][0], c='r', marker='o', s=700)  # 终点
        plt.scatter(d4[:, 1][len(d3)-1], d4[:, 0][len(d3)-1],
                    c='b', marker='o', s=700)  # 起点
        _ldd += 1
        D5.append(d4)

    plt.show()


def get_people_in_map():
    data_set, start_points, place_points ,break_points,place_map_points= read_client_data(1001)  # 读取人员信息
    points, roadLines, roadpoint = ng31. view_maps2(True)  # 读取地图

    npallp = np.array(points)
    # sd1 = np.array(data_set).tolist()  # np.ndarray()
    # sd0 =s22.msort(sd1)

    dat = data_set["longitude"].to_numpy()
    ret = []
    for _val in dat:
        minay = abs(npallp[:, 0]-_val)
        ret.append(np.argmin(minay))
        # print(,len(minay))
    ret = np.array(ret)

    start_id = []
    danp = np.array(start_points)
    for _val in danp[:, 0]:
        minay = abs(npallp[:, 0]-_val)
        start_id.append(np.argmin(minay))

    place_id = []
    place_points = np.array(place_points)
    for _val in place_points[:, 0]:
        minay = abs(npallp[:, 0]-_val)
        place_id.append(np.argmin(minay))

    break_id=[]
    break_points = np.array(break_points)
    for _val in break_points[:, 0]:
        minay = abs(npallp[:, 0]-_val)
        break_id.append(np.argmin(minay))
    # place_id = np.array(place_id)
    # print(place_id, break_id)
    data4 = pd.DataFrame(ret, columns=['id_in_map'])
    data_set = pd.concat([data_set, data4], axis=1)

    print(data_set)
# def _main_fun(sdo0,round_id):
    out_edges, dictpoints = ng31.perdata(roadLines, points)  # 修正数据
    # rescue_peoples = fun.read_client_path_new(round_id)  # 读取行人数据
    # poeple_info = fix_people_id(points, rescue_peoples, roadpoint)
    gant = ng31.mnx(out_edges, dictpoints)
    ps = []
    for sid in start_id:
        for eid in place_id:
            ps.append(nx.astar_path(gant, sid, eid))
    # print(npallp)
    # GET_my_path(npallp,ps)
    return ps, points

    # fun.toJons(addd, "./data/data2cpp.json")
    # fun.toJonsPeolpes(sd0)
    # gen_people_path()
    # points = fun.view_maps(True)
    # plt.show()
    # filter_people()  # 过滤一些
    # read_txt()


def get_xyposi():
    ps, points = get_people_in_map()
    xyps = []

    for p in ps:
        val = []
        for xy in p:
            val.append(points[xy])
        xyps.append(val)

    print(xyps[0])
# get_people_in_map()